package com.min.redis.application.managetment.rank;

import com.min.redis.api.manager.RankManager;
import com.min.redis.api.response.RankItemResponse;
import com.min.redis.application.managetment.util.RankKeyUtil;
import com.min.redis.common.enums.base.ErrorCodeEnum;
import com.min.redis.common.exception.BizException;
import com.min.redis.common.util.jedis.JedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import redis.clients.jedis.resps.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
public class RankManagerImpl implements RankManager {
    private final String RANK_SONGS_KEY = "rank:song";
    private final String RANK_SONGS_MINUTE_KEY = "rank_song_minute:";
    private final String RANK_SONGS_HOUR_KEY = "rank_song_hour:";

    /**
     * 总排行
     * @return
     */
    @Override
    public List<RankItemResponse> getRanks() {
        return getRankListByKey(RANK_SONGS_KEY);
    }

    @Override
    public Boolean addScore(String member) {
        String minuteRankKey = RANK_SONGS_MINUTE_KEY.concat(String.valueOf(RankKeyUtil.rankMinuteKey()));
        String hourRankKey = RANK_SONGS_HOUR_KEY.concat(String.valueOf(RankKeyUtil.rankHourKey()));
        if(StringUtils.isBlank(member)){
            throw new BizException(ErrorCodeEnum.PARAM_ILLEGAL,"需要更新的歌曲名为空");
        }
        JedisUtil.zincrby(minuteRankKey,member,1);
        // 小时榜数据存在时，同步更新，否则查询时重新聚合
        if(JedisUtil.exists(hourRankKey)){
            JedisUtil.zincrby(hourRankKey,member,1);
        }
        return true;
    }

    /**
     * 分钟榜
     * @return
     */
    @Override
    public List<RankItemResponse> getMinuteRank() {
        String minuteKey = RANK_SONGS_MINUTE_KEY.concat(String.valueOf(RankKeyUtil.rankMinuteKey()));
        return getRankListByKey(minuteKey);
    }

    @Override
    public List<RankItemResponse> getHourRank() {
        String hourKey = RANK_SONGS_HOUR_KEY.concat(String.valueOf(RankKeyUtil.rankHourKey()));
        if(!JedisUtil.exists(hourKey)){
            // 统计前60分钟的数据
            long minuteKeyValue = RankKeyUtil.rankMinuteKey();
            List<String> minuteKeys = new ArrayList<>();
            for (int i = 0; i < 60; i++) {
                minuteKeys.add(RANK_SONGS_MINUTE_KEY.concat(String.valueOf(minuteKeyValue-i)));
                JedisUtil.zunion(hourKey,minuteKeys);
            }

        }
        return getRankListByKey(hourKey);
    }

    private List<RankItemResponse> getRankListByKey(String key){
        List<Tuple> songs_ranks =  JedisUtil.zrevrangeAllWithScores(key);
        if(Objects.isNull(songs_ranks)){
            throw new BizException(ErrorCodeEnum.DATA_NOT_EXIST,"没有相应数据");
        }
        return songs_ranks.stream().map(tuple -> new RankItemResponse(tuple.getElement(),tuple.getScore())).collect(Collectors.toList());
    }
}
